<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>计算属性-图表响应</title>
    <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
</head>
<body>
    <div id="应用"></div>
</body>
<script>
    const {createApp: 创建, ref: 引用, computed: 计算, onMounted: 挂载钩子, watch: 侦听, nextTick: 下一帧} = Vue 

    const 根组件 = {
        template: `
            <button @click="增加值">增加值</button>
            <p>值: {{值}}</p>
            <p>计算属性: {{计算值}}</p>
            <chart :值="值" :计算值="计算值"></chart>
        `,

        setup() {
            const 值 = 引用(0)
            const 计算值 = 计算(() => 值.value * 2)

            const 增加值 = () => 值.value ++

            return {值, 计算值, 增加值}
        }
    }

    const 图表组件 = {
        template: `
            <canvas ref="画布" width="300" height="150"></canvas>
        `,

        props: {
            值: {
                type: Number,
                required: true,
            },
            计算值: {
                type: Number,
                required: true,
            }
        },
        setup(props) {
            const 画布 = 引用(null)
            let 图表实例 = null

            挂载钩子(() => {
                图表实例 = new Chart(画布.value.getContext('2d'), {
                    type: 'bar',
                    data: {
                        labels: ['原始值与计算值'],
                        datasets: [
                            {
                                label: '原始值',
                                data: [props.值],
                                backgroundColor: 'skyblue',
                            },
                            {
                                label: '计算值',
                                data: [props.计算值],
                                backgroundColor: 'skyblue',
                            },
                    ]
                    },
                    options: {
                        responsitive: false,
                        animation: false,
                        scale: {
                            y: {beginAtZero: true}
                        }
                    }
                })
            })

            侦听(() => [props.值, props.计算值], ([新值, 新计算值]) => {
                if(图表实例) {
                    图表实例.data.datasets[0].data[0] = 新值 
                    图表实例.data.datasets[1].data[0] = 新计算值 
                    图表实例.update()
                }
            })

            return {画布, }
        }
    }

    const 应用 = 创建(根组件)
    应用.component('chart', 图表组件)
    应用.mount('#应用')
</script>
</html>
